#include "thread.h"

namespace common {

  Thread::Thread(const string& name)
  {
  }

  Thread::Thread(OnceTask&& task, const string& name, bool join)
  {
    //t_ = boost::make_shared<boost::thread>(task);
    t_ = std::make_shared<std::thread>(task);
    if (join) {
      t_->join();
    } else {
      t_->detach();
    }
  }

  Thread::~Thread()
  {

  }

  void Thread::Poll()
  {
    {
      std::lock_guard<std::mutex> guard(init_mtx_);
      if (init_) {
        return;
      }
      init_ = true;
    }

    t_ = std::make_shared<std::thread>([this] () {
      TaskLoop();
    });
    t_->detach();

  }


  void Thread::TaskLoop()
  {
    std::unique_lock<std::mutex> lk(take_mtx_);
    for (;;) {
      take_var_.wait(lk,[this]() {
        return !tasks_.empty() || exit_;
      });
      if (exit_) {
        break;
      }

      ThreadTaskPtr task = nullptr;
      {
        std::lock_guard<std::mutex> guard(task_mtx_);
        if (!tasks_.empty()) {
          task = tasks_.front();
          tasks_.remove(task);
        }
      }
      if (task) {
        task->Run();
      }
    }
  }


  void Thread::Post(const ThreadTaskPtr& task)
  {
    std::lock_guard<std::mutex> guard(task_mtx_);
    tasks_.push_back(task);
    take_var_.notify_one();
  }

  void Thread::Exit()
  {
    exit_ = true;
    take_var_.notify_all();
  }


}
